//给你一个整数 n ，对于 0 <= i <= n 中的每个 i ，计算其二进制表示中 1 的个数 ，返回一个长度为 n + 1 的数组 ans 作为答案。 
//
//
// 
//
// 
// 
// 示例 1： 
//
// 
//输入：n = 2
//输出：[0,1,1]
//解释：
//0 --> 0
//1 --> 1
//2 --> 10
// 
//
// 示例 2： 
//
// 
//输入：n = 5
//输出：[0,1,1,2,1,2]
//解释：
//0 --> 0
//1 --> 1
//2 --> 10
//3 --> 11
//4 --> 100
//5 --> 101
// 
//
// 
//
// 提示： 
//
// 
// 0 <= n <= 105 
// 
//
// 
//
// 进阶： 
//
// 
// 很容易就能实现时间复杂度为 O(n log n) 的解决方案，你可以在线性时间复杂度 O(n) 内用一趟扫描解决此问题吗？ 
// 你能不使用任何内置函数解决此问题吗？（如，C++ 中的 __builtin_popcount ） 
// 
// 
// 
// Related Topics 位运算 动态规划 
// 👍 840 👎 0

package com.cute.leetcode.editor.cn;
public class CountingBits {
    public static void main(String[] args) {
        Solution solution = new CountingBits().new Solution();
    }
    //leetcode submit region begin(Prohibit modification and deletion)
    class Solution {
        /**
         * 偷懒可以直接使用java中的 Integer.bitCount(i)，就是时间效率低了一些，使用j &= (j-1)效率也不高
         * 可以根据奇偶来进行判断，奇数的话一定比前一个元素1的个数多1，偶数的话一定和上一个偶数的1的个数相等
         * 输入：n = 5
         * 输出：[0,1,1,2,1,2]
         */
        public int[] countBits(int n) {
            /*int[] ans = new int[n+1];
            for (int i = 0; i < n+1 ; i++) {
                int j = i;
                while (j!=0){
                    j &= (j-1);
                    ans[i]++;
                }
            }
            return ans;*/
            int[] ans = new int[n+1];
            ans[0] = 0 ;
            for (int i = 0; i <=n  ; i++) {
                if ((i&1) == 1) ans[i] = ans[i-1]+1;//奇数
                else ans[i] = ans[i/2];
            }
            return ans;
        }
    }
//leetcode submit region end(Prohibit modification and deletion)

}